contents

PostgreSQL에서 jsonb 는 JSON(JavaScript Object Notation) 데이터를 분해된 바이너리 형식으로 저장하는 데 사용되는 데이터 타입입니다. 이는 텍스트 기반의 형제인 json 타입보다 효율적인 쿼리 및 인덱싱에 고도로 최적화되어 있어, 대부분의 시나리오에서 JSON 데이터를 처리하기 위한 우선적인 선택지입니다.


핵심적인 차이: json vs. jsonb ⚖️

PostgreSQL은 JSON 데이터를 저장하기 위한 두 가지 데이터 타입을 제공하며, 그 차이를 이해하는 것이 매우 중요합니다.

1. json (텍스트 기반)

2. jsonb (바이너리 기반)

특징 json jsonb
저장 방식 일반 텍스트 분해된 바이너리 형식
입력 속도 더 빠름 (처리 없음) 더 느림 (파싱 필요)
쿼리 속도 느림 (매 쿼리마다 재파싱) 훨씬 빠름 (이미 파싱 및 인덱싱됨)
포맷 보존 공백, 키 순서, 중복 키 보존 공백, 키 순서, 중복 키 보존 안 함
권장 사항 유효성 검사나 레거시 시스템에만 사용 거의 모든 새로운 애플리케이션에 사용

jsonb 사용법: 쿼리 및 연산자 🚀

products 테이블에 jsonb 컬럼으로 제품 메타데이터를 저장한다고 가정해 봅시다.

CREATE TABLE products (
    id SERIAL PRIMARY KEY,
    name TEXT NOT NULL,
    data JSONB
);

INSERT INTO products (name, data) VALUES
('노트북', '{ "price": 1200, "brand": "TechCorp", "specs": { "ram": 16, "storage": 512 }, "tags": ["electronics", "computer"] }'),
('마우스', '{ "price": 25, "brand": "TechCorp", "specs": { "wireless": true }, "tags": ["electronics", "accessory"] }');

주요 연산자

-- 노트북의 'specs' 객체 가져오기
SELECT data -> 'specs' FROM products WHERE name = '노트북';
-- 결과: { "ram": 16, "storage": 512 } (jsonb 타입)
-- 'TechCorp' 브랜드의 제품 찾기
SELECT name FROM products WHERE data ->> 'brand' = 'TechCorp';
-- 결과: 노트북, 마우스
-- 노트북의 RAM 크기 가져오기
SELECT data #> '{specs,ram}' FROM products WHERE name = '노트북';
-- 결과: 16 (jsonb 타입)
-- RAM이 16GB인 제품 찾기
SELECT name FROM products WHERE data #>> '{specs,ram}' = '16';
-- 결과: 노트북
-- 'TechCorp'에서 만든 모든 제품 찾기
SELECT name FROM products WHERE data @> '{"brand": "TechCorp"}';

-- 무선 기능이 있는 모든 제품 찾기
SELECT name FROM products WHERE data @> '{"specs": {"wireless": true}}';

jsonb 컬럼 인덱싱 (성능의 핵심)

jsonb 컬럼에 대한 쿼리를 빠르게 만들려면 반드시 인덱스를 생성해야 합니다. 인덱스가 없으면 PostgreSQL은 전체 테이블을 스캔하여 모든 행을 읽고 그 안의 JSONB 데이터를 파싱해야 합니다.

GIN (Generalized Inverted Index)

GIN 인덱스는 jsonb 데이터에 가장 일반적이고 강력한 인덱스 유형입니다. 각 JSONB 도큐먼트 내의 키와 값에 대한 인덱스를 생성합니다.

GIN 인덱스 생성:

CREATE INDEX idx_products_data ON products USING GIN (data);

이 단일 인덱스는 다음과 같은 키 존재 여부 및 포함 연산자를 사용하는 쿼리의 속도를 높여줍니다.

예를 들어, GIN 인덱스를 생성한 후 다음 쿼리는 매우 빨라집니다.

-- 이 쿼리는 이제 전체 테이블 스캔 대신 GIN 인덱스를 사용합니다.
SELECT name FROM products WHERE data @> '{"brand": "TechCorp"}';

결론적으로, jsonb는 PostgreSQL에 상당한 이점을 제공하는 강력한 기능으로, NoSQL 문서 저장소의 유연성과 선도적인 관계형 데이터베이스의 트랜잭션 무결성 및 성숙한 생태계를 효과적으로 결합합니다.

references